package mysgoog.MC;

import java.util.Vector;

import mysgoog.board.Board;
import mysgoog.board.DragonBoard;
import mysgoog.bot.Config;
import mysgoog.gtp.Color;
import mysgoog.gtp.Vertex;
import mysgoog.util.Lib;
import mysgoog.bot.algo.*;

public class BasActionMgr {
	private boolean[] covering = new boolean[Config.getBoardSize()
			* Config.getBoardSize()];
	private boolean[] visiting = new boolean[Config.getBoardSize()
			* Config.getBoardSize()];
	private boolean[] finddefense = new boolean[Config.getBoardSize()
			* Config.getBoardSize()];
	Color mycolor = null;
	Board board;
	int list = 0;
	Color ucolor;
	int val = 0;
	public Answer[] ret = null;
	Color[] tmpboard;
	Vector<Integer> libvec = null;
	private Evaluator eva;

	final public int maxlib = 4;
	final public int maxdefense = 4;

	public BasActionMgr(Color mc, Board board) {
		mycolor = mc;
		ucolor = mycolor.complement();
		for (int i = 0; i < Config.getBoardSize() * Config.getBoardSize(); i++) {
			covering[i] = false;
			visiting[i] = false;
		}
		libvec = new Vector<Integer>();
		ret = new Answer[Config.getBoardSize() * Config.getBoardSize() * 100];
		list = 0;
		this.board = board;
		tmpboard = new Color[Config.getBoardSize() * Config.getBoardSize()];
		tryattack(board);
		trydefense(board);
	}

	private void trydefense(Board board) {
		int minlib;
		for (int i = 0; i < Config.getBoardSize() * Config.getBoardSize(); i++)
			tmpboard[i] = board.getStone(i);
		for (minlib = 3; minlib < maxdefense; minlib++) {
			for (int tmp = 0; tmp < Config.getBoardSize()
					* Config.getBoardSize(); tmp++)
				covering[tmp] = false;
			for (int i = 0; i < Config.getBoardSize() * Config.getBoardSize(); i++) {
				if ((!covering[i]) && (tmpboard[i] == mycolor)) {
					for (int j = 0; j < Config.getBoardSize()
							* Config.getBoardSize(); j++) {
						covering[j] = false;
					}
					libvec.clear();
					checklib(i, mycolor);
					// //Lib.debug("Defense");
					// //Lib.debug(((Integer) i).toString());
					// ib.debug(((Integer) libvec.size()).toString());
					if (libvec.size() == minlib) {
						for (int j = 0; j < Config.getBoardSize()
								* Config.getBoardSize(); j++)
							finddefense[j] = false;
						findnextmove(i, i, minlib);
					}
				}
			}
		}
	}

	private void tryattack(Board board) {
		int free;
		int tval;

		for (int i = 0; i < Config.getBoardSize() * Config.getBoardSize(); i++) {
			covering[i] = false;
			tmpboard[i] = board.getStone(i);
			// //Lib.debug(tmpboard[i].toString());
		}
		for (int i = 0; i < Config.getBoardSize() * Config.getBoardSize(); i++)
			if (tmpboard[i] == ucolor) {
				if (!covering[i]) {
					for (int j = 0; j < Config.getBoardSize()
							* Config.getBoardSize(); j++)
						covering[j] = false;
					libvec.clear();
					checklib(i, ucolor);
					free = libvec.size();
					// //Lib.debug("free");
					// //Lib.debug(((Integer) i).toString());
					// //Lib.debug(((Integer) free).toString());
					if (free == 1) {
						list++;
						ret[list] = new Answer(libvec.get(0), 120);
						// //Lib.debug("Place");
						// //Lib.debug(((Integer) list).toString());
						// //Lib.debug(((Integer) libvec.get(0)).toString());
					} else if (free <= maxlib) {
						val = -10000;
						for (int u = 0; u < (int) free; u++)
							for (int v = 0; v < (int) free; v++)
								if (u != v) {
									tmpboard[libvec.get(u)] = mycolor;
									for (int tmp = 0; tmp < Config
											.getBoardSize()
											* Config.getBoardSize(); tmp++)
										visiting[tmp] = false;
									int lib1 = countlib(i);
									tmpboard[libvec.get(v)] = ucolor;
									for (int tmp = 0; tmp < Config
											.getBoardSize()
											* Config.getBoardSize(); tmp++)
										visiting[tmp] = false;
									int lib2 = countlib(i);

									if ((lib1 == 1) && (lib2 > 0))
										tval = 0;
									else
										tval = 120 - 20 * lib2;
									// //Lib.debug("tval");
									// //Lib.debug((((Integer) libvec.get(u))
									// .toString()));
									// //Lib.debug((((Integer) libvec.get(v))
									// .toString()));
									// .debug((((Integer) tval).toString()));
									boolean flag = false;
									if (val < tval) {
										val = tval;
										flag = true;
									}
									if (tval >= 60)
										flag = true;

									if (flag) {
										list++;
										ret[list] = new Answer(libvec.get(u),
												tval);
										// //Lib.debug("Place");
										// Lib.debu/g(((Integer)
										// list).toString());
										// Lib.debug(((Integer) libvec.get(u))
										// .toString());
									}

									tmpboard[libvec.get(u)] = Color.EMPTY;
									tmpboard[libvec.get(v)] = Color.EMPTY;
								}
					}
				}
			}

	}

	private void checklib(int place, Color color) {
		int x, y;

		if (tmpboard[place] == color.complement())
			return;
		if (covering[place])
			return;
		covering[place] = true;
		if (tmpboard[place] == Color.EMPTY) {
			libvec.add(place);
			return;
		}
		x = Config.getEmptyBoard().posX(place);
		y = Config.getEmptyBoard().posY(place);
		if (x - 1 >= 0)
			checklib(Config.getEmptyBoard().makePos(x - 1, y), color);
		if (x + 1 < Config.getBoardSize())
			checklib(Config.getEmptyBoard().makePos(x + 1, y), color);
		if (y - 1 >= 0)
			checklib(Config.getEmptyBoard().makePos(x, y - 1), color);
		if (y + 1 < Config.getBoardSize())
			checklib(Config.getEmptyBoard().makePos(x, y + 1), color);
	}

	private int countlib(int place) {
		int ret = 0;
		int x, y;
		if (visiting[place])
			return 0;
		visiting[place] = true;
		if (tmpboard[place] == Color.EMPTY)
			return 1;
		x = Config.getEmptyBoard().posX(place);
		y = Config.getEmptyBoard().posY(place);
		if (x - 1 >= 0)
			ret = ret + countlib(Config.getEmptyBoard().makePos(x - 1, y));
		if (x + 1 < Config.getBoardSize())
			ret = ret + countlib(Config.getEmptyBoard().makePos(x + 1, y));
		if (y - 1 >= 0)
			ret = ret + countlib(Config.getEmptyBoard().makePos(x, y - 1));
		if (y + 1 < Config.getBoardSize())
			ret = ret + countlib(Config.getEmptyBoard().makePos(x, y + 1));
		return ret;
	}

	private void findnextmove(int origin, int place, int minlib) {
		int x, y;
		if (tmpboard[place] == Color.EMPTY) {
			tmpboard[place] = mycolor;
			for (int i = 0; i < Config.getBoardSize() * Config.getBoardSize(); i++)
				visiting[i] = false;
			int lib = countlib(place);
			int tmp = 40 + (lib - minlib - 1) * 50 / (minlib * minlib * minlib);
			if (tmp > 60) {
				list++;
				ret[list] = new Answer(place, tmp, origin);
			}
			tmpboard[place] = Color.EMPTY;
		} else {
			if (tmpboard[place] == ucolor)
				return;
			if (finddefense[place])
				return;
			x = Config.getEmptyBoard().posX(place);
			y = Config.getEmptyBoard().posY(place);
			finddefense[place] = true;
			if (x - 1 >= 0)
				findnextmove(origin, Config.getEmptyBoard().makePos(x - 1, y),
						minlib);
			if (x + 1 < Config.getBoardSize())
				findnextmove(origin, Config.getEmptyBoard().makePos(x + 1, y),
						minlib);
			if (y - 1 >= 0)
				findnextmove(origin, Config.getEmptyBoard().makePos(x, y - 1),
						minlib);
			if (y + 1 < Config.getBoardSize())
				findnextmove(origin, Config.getEmptyBoard().makePos(x, y + 1),
						minlib);
		}
	}

	public int getnumber() {
		return list;
	}

	public Vector<Integer> getPlace() {
		final int max = 10000;
		final int mineva = 1;
		eva = new Evaluator((DragonBoard) board);
		Vector<Integer> res = new Vector<Integer>();
		for (int times = 0; times < 5; times++) {
			int best = max;
			for (int i = 1; i <= list; i++) {
				if ((best == max) || ((ret[i].value >= ret[best].value))
						&& (board.isLegal(mycolor, ret[i].place))
						&& ((eva.evaluate(ret[i].place, mycolor, -1)) > mineva)
						&& ((eva.easyEvaluate(ret[i].place, mycolor))))
					best = i;
			}
			if (best <= list) {
				if (!res.contains(ret[best].place))
					res.add(ret[best].place);
				ret[best].value = -1000;
			}
		}
		return res;

		// //Lib.debug("LIST");
		// //Lib.debug((((Integer) list).toString()));
		// //Lib.debug((((Integer) ret[best].origin).toString()));

	}
}